package com.gzz.common.aop;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.cache.Cache;
import com.gzz.common.filter.JwtTools;
import com.gzz.manage.sys.log.Log;
import com.gzz.manage.sys.log.LogDao;
import com.gzz.manage.sys.user.User;

import lombok.extern.slf4j.Slf4j;

/**
 * @功能描述 【日志记录】切面
 * @author 高振中
 * @date 2021-03-12
 */
@Aspect
@Component
@Slf4j
public class AutoLogAop {
	@Autowired
	private ObjectMapper mapper;
	@Autowired
	private HttpServletRequest request;
	@Autowired
	private Cache<Integer, User> userCache;// 用于存放用户登录信息的guava缓存
	@Autowired
	private LogDao logDao; // 注入【系统日志】数据访问层

//	@Before("within(com.gzz.manage..*) && @annotation(autoLog)")
	@Around("execution(public * com.gzz.manage..*.*Controller.*(..)) && @annotation(autoLog)")
	public Object beforeLog(ProceedingJoinPoint point, AutoLog autoLog) {
		Object result = null;
		try {
			result = point.proceed();
			User user = User.builder().userId(-1).name("见参数").build();// 登录时没有用户名与ID
			if (!StringUtils.isEmpty(request.getHeader("token")))
				user = userCache.getIfPresent(JwtTools.getUserId(request.getHeader("token")));

			Log vo = Log.builder().ip(request.getRemoteAddr()).userId(user.getUserId()).userName(user.getName()).title(autoLog.value()).url(request.getServletPath())
					.method(point.getSignature().toShortString()).requestType(request.getMethod()).result(mapper.writeValueAsString(result))
					.params("[body]:" + mapper.writeValueAsString(point.getArgs()) + ",[param]:" + mapper.writeValueAsString(request.getParameterMap())).build();
			logDao.save(vo);
		} catch (Throwable e) {
			log.error("拦截日志时发生异常！", e);
		}
		return result;
	}

}
